home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / viewers / hv12 / src / jdcolor.c < prev    next >
C/C++ Source or Header  |  1992-07-16  |  9KB  |  303 lines

  1. /*
  2.  * jdcolor.c
  3.  *
  4.  * Copyright (C) 1991, 1992, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains output colorspace conversion routines.
  9.  * These routines are invoked via the methods color_convert
  10.  * and colorout_init/term.
  11.  */
  12.  
  13. #include "jinclude.h"
  14. extern unsigned char *range_limit;
  15.  
  16. /**************** YCbCr -> RGB conversion: most common case **************/
  17.  
  18. /*
  19.  * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
  20.  * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
  21.  * The conversion equations to be implemented are therefore
  22.  *    R = Y                + 1.40200 * Cr
  23.  *    G = Y - 0.34414 * Cb - 0.71414 * Cr
  24.  *    B = Y + 1.77200 * Cb
  25.  * where Cb and Cr represent the incoming values less MAXJSAMPLE/2.
  26.  * (These numbers are derived from TIFF Appendix O, draft of 4/10/91.)
  27.  *
  28.  * To avoid floating-point arithmetic, we represent the fractional constants
  29.  * as integers scaled up by 2^14 (about 4 digits precision); we have to divide
  30.  * the products by 2^14, with appropriate rounding, to get the correct answer.
  31.  * Notice that Y, being an integral input, does not contribute any fraction
  32.  * so it need not participate in the rounding.
  33.  *
  34.  * For even more speed, we avoid doing any multiplications in the inner loop
  35.  * by precalculating the constants times Cb and Cr for all possible values.
  36.  * For 8-bit JSAMPLEs this is very reasonable (only 256 table entries); for
  37.  * 12-bit samples it is still acceptable.  It's not very reasonable for 16-bit
  38.  * samples, but if you want lossless storage you shouldn't be changing
  39.  * colorspace anyway.
  40.  * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
  41.  * values for the G calculation are left scaled up, since we must add them
  42.  * together before rounding.
  43.  */
  44.  
  45. #define SCALEBITS    14
  46. #define ONE_HALF    ((INT32) 1 << (SCALEBITS-1))
  47. #define FIX(x)        ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
  48.  
  49. static INT16 * Cr_r_tab;    /* => table for Cr to R conversion */
  50. static INT16 * Cb_b_tab;    /* => table for Cb to B conversion */
  51. static INT32 * Cr_g_tab;    /* => table for Cr to G conversion */
  52. static INT32 * Cb_g_tab;    /* => table for Cb to G conversion */
  53.  
  54.  
  55. /*
  56.  * Initialize for colorspace conversion.
  57.  */
  58.  
  59. METHODDEF void
  60. ycc_rgb_init (decompress_info_ptr cinfo)
  61. {
  62. #ifdef SIXTEEN_BIT_SAMPLES
  63.   INT32 i, x2;
  64. #else
  65.   int i, x2;            /* smart compiler may do 16x16=>32 multiply */
  66. #endif
  67.   SHIFT_TEMPS
  68.  
  69.   Cr_r_tab = (INT16 *) (*cinfo->emethods->alloc_small)
  70.                 ((MAXJSAMPLE+1) * SIZEOF(INT16));
  71.   Cb_b_tab = (INT16 *) (*cinfo->emethods->alloc_small)
  72.                 ((MAXJSAMPLE+1) * SIZEOF(INT16));
  73.   Cr_g_tab = (INT32 *) (*cinfo->emethods->alloc_small)
  74.                 ((MAXJSAMPLE+1) * SIZEOF(INT32));
  75.   Cb_g_tab = (INT32 *) (*cinfo->emethods->alloc_small)
  76.                 ((MAXJSAMPLE+1) * SIZEOF(INT32));
  77.  
  78.   for (i = 0; i <= MAXJSAMPLE; i++) {
  79.     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
  80.     /* The Cb or Cr value we are thinking of is x = i - MAXJSAMPLE/2 */
  81.     x2 = 2*i - MAXJSAMPLE;    /* twice x */
  82.     /* Cr=>R value is nearest int to 1.40200 * x */
  83.     Cr_r_tab[i] = (INT16)
  84.             RIGHT_SHIFT(FIX(1.40200/2) * x2 + ONE_HALF, SCALEBITS);
  85.     /* Cb=>B value is nearest int to 1.77200 * x */
  86.     Cb_b_tab[i] = (INT16)
  87.             RIGHT_SHIFT(FIX(1.77200/2) * x2 + ONE_HALF, SCALEBITS);
  88.     /* Cr=>G value is scaled-up -0.71414 * x */
  89.     Cr_g_tab[i] = (- FIX(0.71414/2)) * x2;
  90.     /* Cb=>G value is scaled-up -0.34414 * x */
  91.     /* We also add in ONE_HALF so that need not do it in inner loop */
  92.     Cb_g_tab[i] = (- FIX(0.34414/2)) * x2 + ONE_HALF;
  93.   }
  94. }
  95.  
  96.  
  97. /*
  98.  * Convert some rows of samples to the output colorspace.
  99.  */
  100.  
  101. METHODDEF void
  102. ycc_rgb_convert (decompress_info_ptr cinfo, int num_rows, long num_cols,
  103.          JSAMPIMAGE input_data, JSAMPIMAGE output_data)
  104. {
  105. #ifdef SIXTEEN_BIT_SAMPLES
  106.   register UINT16 y, cb, cr;
  107.   register INT32 x;
  108. #else
  109.   register int y, cb, cr;
  110.   register int x;
  111. #endif
  112.   register JSAMPROW inptr0, inptr1, inptr2;
  113.   register JSAMPROW outptr0, outptr1, outptr2;
  114.   long col;
  115.   int row;
  116.   SHIFT_TEMPS
  117.   
  118.   for (row = 0; row < num_rows; row++) {
  119.     inptr0 = input_data[0][row];
  120.     inptr1 = input_data[1][row];
  121.     inptr2 = input_data[2][row];
  122.     outptr0 = output_data[0][row];
  123.     outptr1 = output_data[1][row];
  124.     outptr2 = output_data[2][row];
  125.     for (col = num_cols; col > 0; col--) {
  126.       y  = GETJSAMPLE(*inptr0++);
  127.       cb = GETJSAMPLE(*inptr1++);
  128.       cr = GETJSAMPLE(*inptr2++);
  129.       /* Note: if the inputs were computed directly from RGB values,
  130.        * range-limiting would be unnecessary here; but due to possible
  131.        * noise in the DCT/IDCT phase, we do need to apply range limits.
  132.        */
  133.       *outptr0++ = range_limit[y + Cr_r_tab[cr]]; /* red */
  134. /*
  135.       if (x < 0) x = 0;
  136.       else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
  137.       *outptr0++ = (JSAMPLE) x;
  138. */
  139.       *outptr1++ = range_limit[y + ((int) RIGHT_SHIFT(Cb_g_tab[cb] + Cr_g_tab[cr], SCALEBITS))];
  140. /*
  141.       if (x < 0) x = 0;
  142.       else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
  143.       *outptr1++ = (JSAMPLE) x;
  144. */
  145.       *outptr2++ = range_limit[y + Cb_b_tab[cb]]; /* blue */
  146. /*
  147.       if (x < 0) x = 0;
  148.       else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
  149.       *outptr2++ = (JSAMPLE) x;
  150. */
  151.     }
  152.   }
  153. }
  154.  
  155.  
  156. /*
  157.  * Finish up at the end of the file.
  158.  */
  159.  
  160. METHODDEF void
  161. ycc_rgb_term (decompress_info_ptr cinfo)
  162. {
  163.   /* no work (we let free_all release the workspace) */
  164. }
  165.  
  166.  
  167. /**************** Cases other than YCbCr -> RGB **************/
  168.  
  169.  
  170. /*
  171.  * Initialize for colorspace conversion.
  172.  */
  173.  
  174. METHODDEF void
  175. null_init (decompress_info_ptr cinfo)
  176. /* colorout_init for cases where no setup is needed */
  177. {
  178.   /* no work needed */
  179. }
  180.  
  181.  
  182. /*
  183.  * Color conversion for no colorspace change: just copy the data.
  184.  */
  185.  
  186. METHODDEF void
  187. null_convert (decompress_info_ptr cinfo, int num_rows, long num_cols,
  188.           JSAMPIMAGE input_data, JSAMPIMAGE output_data)
  189. {
  190.   short ci;
  191.  
  192.   for (ci = 0; ci < cinfo->num_components; ci++) {
  193.     jcopy_sample_rows(input_data[ci], 0, output_data[ci], 0,
  194.               num_rows, num_cols);
  195.   }
  196. }
  197.  
  198.  
  199. /*
  200.  * Color conversion for grayscale: just copy the data.
  201.  * This also works for YCbCr/YIQ -> grayscale conversion, in which
  202.  * we just copy the Y (luminance) component and ignore chrominance.
  203.  */
  204.  
  205. METHODDEF void
  206. grayscale_convert (decompress_info_ptr cinfo, int num_rows, long num_cols,
  207.            JSAMPIMAGE input_data, JSAMPIMAGE output_data)
  208. {
  209.   jcopy_sample_rows(input_data[0], 0, output_data[0], 0,
  210.             num_rows, num_cols);
  211. }
  212.  
  213.  
  214. /*
  215.  * Finish up at the end of the file.
  216.  */
  217.  
  218. METHODDEF void
  219. null_term (decompress_info_ptr cinfo)
  220. /* colorout_term for cases where no teardown is needed */
  221. {
  222.   /* no work needed */
  223. }
  224.  
  225.  
  226.  
  227. /*
  228.  * The method selection routine for output colorspace conversion.
  229.  */
  230.  
  231. GLOBAL void
  232. jseldcolor (decompress_info_ptr cinfo)
  233. {
  234.   /* Make sure num_components agrees with jpeg_color_space */
  235.   switch (cinfo->jpeg_color_space) {
  236.   case CS_GRAYSCALE:
  237.     if (cinfo->num_components != 1)
  238.       ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
  239.     break;
  240.  
  241.   case CS_RGB:
  242.   case CS_YCbCr:
  243.   case CS_YIQ:
  244.     if (cinfo->num_components != 3)
  245.       ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
  246.     break;
  247.  
  248.   case CS_CMYK:
  249.     if (cinfo->num_components != 4)
  250.       ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
  251.     break;
  252.  
  253.   default:
  254.     ERREXIT(cinfo->emethods, "Unsupported JPEG colorspace");
  255.     break;
  256.   }
  257.  
  258.   /* Set color_out_comps and conversion method based on requested space */
  259.   switch (cinfo->out_color_space) {
  260.   case CS_GRAYSCALE:
  261.     cinfo->color_out_comps = 1;
  262.     if (cinfo->jpeg_color_space == CS_GRAYSCALE ||
  263.     cinfo->jpeg_color_space == CS_YCbCr ||
  264.     cinfo->jpeg_color_space == CS_YIQ) {
  265.       cinfo->methods->color_convert = grayscale_convert;
  266.       cinfo->methods->colorout_init = null_init;
  267.       cinfo->methods->colorout_term = null_term;
  268.     } else
  269.       ERREXIT(cinfo->emethods, "Unsupported color conversion request");
  270.     break;
  271.  
  272.   case CS_RGB:
  273.     cinfo->color_out_comps = 3;
  274.     if (cinfo->jpeg_color_space == CS_YCbCr) {
  275.       cinfo->methods->color_convert = ycc_rgb_convert;
  276.       cinfo->methods->colorout_init = ycc_rgb_init;
  277.       cinfo->methods->colorout_term = ycc_rgb_term;
  278.     } else if (cinfo->jpeg_color_space == CS_RGB) {
  279.       cinfo->methods->color_convert = null_convert;
  280.       cinfo->methods->colorout_init = null_init;
  281.       cinfo->methods->colorout_term = null_term;
  282.     } else
  283.       ERREXIT(cinfo->emethods, "Unsupported color conversion request");
  284.     break;
  285.  
  286.   default:
  287.     /* Permit null conversion from CMYK or YCbCr to same output space */
  288.     if (cinfo->out_color_space == cinfo->jpeg_color_space) {
  289.       cinfo->color_out_comps = cinfo->num_components;
  290.       cinfo->methods->color_convert = null_convert;
  291.       cinfo->methods->colorout_init = null_init;
  292.       cinfo->methods->colorout_term = null_term;
  293.     } else            /* unsupported non-null conversion */
  294.       ERREXIT(cinfo->emethods, "Unsupported color conversion request");
  295.     break;
  296.   }
  297.  
  298.   if (cinfo->quantize_colors)
  299.     cinfo->final_out_comps = 1;    /* single colormapped output component */
  300.   else
  301.     cinfo->final_out_comps = cinfo->color_out_comps;
  302. }
  303.